﻿using System.Net;

namespace Toybox.NicoSharp.Abstracts
{
	using Extensions;
	using Utilities;

	/// <summary>
	/// 各種 Content の Abstract クラス
	/// </summary>
	public abstract class AbstractContent
	{

		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="cookies"></param>
		public AbstractContent(CookieCollection cookies)
		{
			this.Cookies = cookies;
		}

		#endregion Constructor


		#region Public Members

		/// <summary>
		/// クッキー
		/// </summary>
		public CookieCollection Cookies
		{
			get { return this._cookies.Coerce(); }
			set { this._cookies = value; }
		}
		private CookieCollection _cookies;

		#endregion Public Members


		#region Protected Methods

		/// <summary>
		/// Get Abstract メソッド
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="url"></param>
		/// <returns></returns>
		protected abstract T Get<T>(string url);

		/// <summary>
		/// Post Abstract メソッド
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="url"></param>
		/// <param name="data"></param>
		/// <returns></returns>
		protected abstract T Post<T>(string url, string data);

		#endregion Protected Methods

	}

	/// <summary>
	/// Xml形式 Content の Abstract クラス
	/// </summary>
	public abstract class AbstractXmlContent : AbstractContent
	{

		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="contentId"></param>
		/// <param name="cookies"></param>
		public AbstractXmlContent(ContentId contentId, CookieCollection cookies)
			: base(cookies)
		{
			this.ContentId = contentId;
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="contentId"></param>
		/// <param name="cookies"></param>
		public AbstractXmlContent(string contentId, CookieCollection cookies)
			: base(cookies)
		{
			this.ContentId = new ContentId(contentId);
		}

		#endregion Constructor


		#region Public Members

		/// <summary>
		/// ContentId
		/// </summary>
		public ContentId ContentId
		{
			get;
			protected set;
		}

		#endregion Public Members


		#region Protected Methods

		/// <summary>
		/// Get メソッド
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="url"></param>
		/// <returns></returns>
		protected override T Get<T>(string url)
		{
			string xml = NicoWebClient.Get(url, this.Cookies);
			return Deserializer.XmlDeserializer<T>(xml);
		}

		/// <summary>
		/// Post メソッド
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="url"></param>
		/// <param name="data"></param>
		/// <returns></returns>
		protected override T Post<T>(string url, string data)
		{
			string xml = NicoWebClient.Post(url, data, this.Cookies);
			return Deserializer.XmlDeserializer<T>(xml);
		}

		#endregion Protected Methods

	}

	/// <summary>
	/// Json形式 Content の Abstract クラス
	/// </summary>
	public abstract class AbstractJsonContent : AbstractContent
	{

		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="cookies"></param>
		public AbstractJsonContent(CookieCollection cookies)
			: base(cookies)
		{
		}

		#endregion Constructor


		#region Protected Methods

		/// <summary>
		/// Get メソッド
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="url"></param>
		/// <returns></returns>
		protected override T Get<T>(string url)
		{
			string json = NicoWebClient.Get(url, this.Cookies);
			return Deserializer.JsonDeserializer<T>(json);
		}

		/// <summary>
		/// Post メソッド
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="url"></param>
		/// <param name="data"></param>
		/// <returns></returns>
		protected override T Post<T>(string url, string data)
		{
			string json = NicoWebClient.Post(url, data, this.Cookies);
			return Deserializer.JsonDeserializer<T>(json);
		}

		#endregion Protected Methods

	}
}
